﻿using System.Collections;
using System.Collections.Generic;
using Assets.AnimationPlayer.Scripts.Animations;
using UnityEngine;

namespace Assets.AnimationPlayer.Scripts.UI
{
    public class AnimationView: MonoBehaviour
    {
        public AnimationSubPage TopPage;
        public AnimationSubPage RightPage;
        public AnimationSubPage LeftPage;

        public GameObject Render3D;
        public Camera RenderTopCamera;
        public Camera RenderLeftCamera;
        public Camera RenderRightCamera;

        internal void Start()
        {
            //return;
            TopPage.TopBarControl.ShowLogo(AnimationVar.AnimationPlayCfg.ColorLogoType);
            RightPage.TopBarControl.ShowLogo(AnimationVar.AnimationPlayCfg.ColorLogoType);
            LeftPage.TopBarControl.ShowLogo(AnimationVar.AnimationPlayCfg.ColorLogoType);

            TopPage.BindClickEvents(AnimationVar.BackToList);
            RightPage.BindClickEvents(AnimationVar.BackToList);
            LeftPage.BindClickEvents(AnimationVar.BackToList);
        }

        private readonly object _lockObject = new object();
        private int _loadingCount;

        private void _loadingStart()
        {
            //return;
            lock (_lockObject)
            {
                _loadingCount = 0;
            }

            StartCoroutine(TopPage.StartLoading(_loadingStarted));
            StartCoroutine(RightPage.StartLoading(_loadingStarted));
            StartCoroutine(LeftPage.StartLoading(_loadingStarted));
        }

        private void _loadingStarted()
        {
            lock (_lockObject)
            {
                _loadingCount++;
                if (_loadingCount == 3)
                {
                    if (string.IsNullOrEmpty(AnimationVar.AnimationPlayCfg.SelectAnimationObj.AnimationPath))
                    {
                        AnimationVar.BackToList();
                    }
                    else
                    {
                        StartCoroutine(_loadAniamtion(AnimationVar.AnimationPlayCfg.SelectAnimationObj.AnimationPath));
                    }
                }
            }
        }


        private void _loadingEnd()
        {
            StartCoroutine(TopPage.StopLoading(_loadingEnded));
            StartCoroutine(RightPage.StopLoading(_loadingEnded));
            StartCoroutine(LeftPage.StopLoading(_loadingEnded));
        }

        private void _loadingEnded()
        {
            lock (_lockObject)
            {
                _loadingCount--;
            }
        }

        private IEnumerator _loadAniamtion(string animationPath)
        {
            //WWW www = new WWW(AniamtionVar.GetFilePath("resources1.assetbundle"));

            //yield return www;
            //if (!string.IsNullOrEmpty(www.error))
            //{
            //    //todo 重启U3d
            //    //AniamtionVar.AnimationPlayCfg.AutoPlay = true;
            //    //AniamtionVar.AnimationPlayCfg.SelectAnimationIndex = -1;
            //    //AniamtionVar.BackToList();
            //    www.Dispose();
            //    AniamtionVar.AnimationPlayCfg.CalArApi.API_ReStart();
            //    yield break;
            //}
            var resourceRequest = Resources.LoadAsync<GameObject>(animationPath);
            while (!resourceRequest.isDone)
            {
                yield return resourceRequest;
            }

            try
            {
                var index = 0;
                var cameras = new List<Camera>() {RenderTopCamera, RenderRightCamera, RenderLeftCamera};
                foreach (var angle in AnimationVar.AnimationPlayCfg.SelectAnimationObj.Angles)
                {
                    if(index >cameras.Count)continue;
                    //var gb = Instantiate(resourceRequest.asset as GameObject, cameras[index].transform.parent);
                    var gb = Instantiate(resourceRequest.asset as GameObject, Render3D.transform);
                    gb.name = "animation_" + index;
                    ChangeLayer(gb.transform, "Player2D");
                    gb.GetComponent<Animation>().Stop();
                    gb.GetComponent<Animation>().playAutomatically = false;
                    //gb.AddComponent<AR_CAT>();
                    var myCamera = cameras[index];
                    _initAnimationAngle(gb, angle, myCamera);
                    myCamera.depth = index;
                    index++;
                }

                bool addcallback = false;
                foreach (Transform tf in Render3D.transform)
                {
                    //var animationTf = tf.GetChild(1);
                    var animationTf = tf;
                    var animationPlayEvents = animationTf.gameObject.AddComponent<AnimationPlayEvents>();
                    if (!addcallback)
                    {
                        addcallback = true;
                        animationPlayEvents.PlayEnd = AnimationPlayEnded;
                        var newAnimation = animationTf.GetComponent<Animation>();
                        var animationEvent = new AnimationEvent
                        {
                            time = newAnimation.clip.length,
                            functionName = "AnimationPlayEnd"
                        };
                        newAnimation.clip.AddEvent(animationEvent);
                    }
                    else
                    {
                        animationPlayEvents.PlayEnd = null;
                    }

                    animationTf.GetComponent<Animation>().Play();
                }
                _loadingEnd();
            }
            catch
            {
                AnimationVar.AnimationPlayCfg.AutoPlay = true;
                AnimationVar.AnimationPlayCfg.SelectAnimationIndex = -1;
                //AniamtionVar.ResetVar();
                //AniamtionVar.BackToList();
                AnimationVar.UnDestoryScene.CallApi.API_ReStart();
            }
        }

        void ChangeLayer(Transform trans, string targetLayer)
        {
            if (LayerMask.NameToLayer(targetLayer) == -1)
            {
                Debug.Log("Layer中不存在,请手动添加LayerName");
                return;
            }
            //遍历更改所有子物体layer
            trans.gameObject.layer = LayerMask.NameToLayer(targetLayer);
            foreach (Transform child in trans)
            {
                ChangeLayer(child, targetLayer);
            }
        }

        private readonly object _lockObject1 = new object();
        public void AnimationPlayEnded()
        {
            lock (_lockObject1)
            {
                foreach (Transform tf in Render3D.transform)
                {
                    for (var i = tf.childCount-1; i >=  0; i--)
                    {
                        var ctf = tf.GetChild(i);
                        if (ctf.name.StartsWith("animation_"))
                        {
                            ctf.GetComponent<AnimationPlayEvents>().PlayEnd = null;
                            ctf.GetComponent<Animation>().Stop();
                            Destroy(ctf.gameObject);
                        }
                    }
                }

            }
            if (AnimationVar.AnimationPlayCfg.SelectAnimationIndex < AnimationVar.AnimationPlayCfg.Cfg.AnimationObjs.Count - 1)
            {
                AnimationVar.AnimationPlayCfg.SelectAnimationIndex += 1;
            }
            else
            {
                AnimationVar.AnimationPlayCfg.SelectAnimationIndex = 0;
            }

            AnimationVar.PlayAnimation();
        }

        private static void _initAnimationAngle(GameObject gb, Angle angle,Camera camera)
        {
            if (camera != null)
            {
                var cameraX = float.Parse(angle.CameraX);
                var cameraY = float.Parse(angle.CameraY);
                var cameraZ = float.Parse(angle.CameraZ);
                var cameraRoateX = float.Parse(angle.CameraRoateX);
                var cameraRoateY = float.Parse(angle.CameraRoateY);
                var cameraRoateZ = float.Parse(angle.CameraRoateZ);
                var cameraFieldView = float.Parse(angle.CameraFieldView);
                var cameraNearClipPlane = float.Parse(angle.CameraNearClipPlane);
                var cameraFarClipPlane = float.Parse(angle.CameraFarClipPlane);

                camera.transform.localRotation = Quaternion.Euler(cameraRoateX, cameraRoateY, cameraRoateZ);
                camera.transform.localPosition = new Vector3(cameraX, cameraY, cameraZ);
                camera.fieldOfView = cameraFieldView;
                camera.nearClipPlane = cameraNearClipPlane;
                camera.farClipPlane = cameraFarClipPlane;
            }

            var x = float.Parse(angle.X);
            var y = float.Parse(angle.Y);
            var z = float.Parse(angle.Z);
            var rx = float.Parse(angle.RoateX);
            var ry = float.Parse(angle.RoateY);
            var rz = float.Parse(angle.RoateZ);
            var s = float.Parse(angle.Scale);
            var flipX = angle.FlipX == "true" ? -1 : 1;
            var flipY = angle.FlipY == "true" ? -1 : 1;
            var flipZ = angle.FlipZ == "true" ? -1 : 1;
            var flip = angle.Flip == "true" ? -1 : 1;

            gb.transform.localScale = new Vector3(flipX, flipY, flipZ) * flip * s;
            gb.transform.localRotation = Quaternion.Euler(rx, ry, rz);
            gb.transform.localPosition = new Vector3(x * flipX, y * flipY, z * flipZ) * flip;
        }

        private bool _isLoad;
        internal void Update()
        {
            if (Input.anyKeyDown)
            {
                if (Input.GetKey(KeyCode.JoystickButton1) ||
                    Input.GetKey(KeyCode.Joystick1Button1) ||
                    Input.GetKey(KeyCode.Joystick2Button1) ||
                    Input.GetKey(KeyCode.Joystick3Button1) ||
                    Input.GetKey(KeyCode.Joystick4Button1) ||
                    Input.GetKey(KeyCode.Joystick5Button1) ||
                    Input.GetKey(KeyCode.Joystick6Button1) ||
                    Input.GetKey(KeyCode.Joystick7Button1) ||
                    Input.GetKey(KeyCode.Joystick8Button1) || Input.GetKey(KeyCode.Escape))
                {
                    Application.Quit();
                    //返回
                    AnimationVar.BackToList();
                }
            }

            if (!_isLoad)
            {
                _isLoad = true;
                _loadingStart();
            }
        }
    }
}
